//
// Created by xwt.
//

#ifndef AB_UTILS_AB_LOGGER_HPP
#define AB_UTILS_AB_LOGGER_HPP

#include <memory>
#include <fstream>
#include <string>
#include <mutex>
#include <ab_common.hpp>


namespace anbantech {
    class ab_logger;
    using ab_logger_ptr=std::shared_ptr<ab_logger>;
    static ab_logger_ptr logger;

#ifndef LOG
#define LOG(LEVEL,...)          { \
    if(unlikely(!logger)) { \
        logger = ab_logger::get_instance(); \
    } \
    logger->log(LEVEL,__VA_ARGS__); \
    }
#endif
#ifndef SETLOGLEVEL
#define SETLOGLEVEL(level) { \
    if(unlikely(!logger)){ \
        logger = ab_logger::get_instance(); \
    } \
    logger->set_log_level(level); \
}

#endif

    enum LogLevel {
        DEBUG,
        INFO,
        WARN,
        ERROR,
        FATAL
    };

    class ab_logger {
    private:
        std::string filename;
        std::ofstream file;
        bool console;
        LogLevel level;
        static std::shared_ptr<ab_logger> instance;
        static std::mutex mtx;
    private:
        explicit ab_logger(bool console = true, LogLevel level = DEBUG);

        // 返回：当前时间的格式化字符串，如"2023-11-18 23:04:24"
        std::string get_current_time();
        static std::string get_moudule_name();

        // 返回：日志级别的字符串表示，如"DEBUG"
        std::string get_log_level(LogLevel level);
    public:
        ab_logger(const ab_logger&) = delete;
        ab_logger& operator=(const ab_logger&) = delete;
        ~ab_logger();
        // 参数：filename - 日志文件名，console - 是否输出到控制台，level - 日志级别
        static ab_logger_ptr get_instance(bool console = true, LogLevel level = DEBUG);
        void set_log_level(LogLevel l = DEBUG);
        void log(LogLevel level, const char *format, ...);
    };

} // anbantech

#endif //AB_UTILS_AB_LOGGER_HPP
